package com.ltmall.api.manager.impl;

import com.ltmall.api.bean.*;
import com.ltmall.api.dao.IAccountDAO;
import com.ltmall.api.dao.IDirectorPrivilegeOrderDAO;
import com.ltmall.api.dao.IDirectorPrivilegePackageDAO;
import com.ltmall.api.dao.impl.SubUnderwritingDAO;
import com.ltmall.api.dao.impl.WalletDAO;
import com.ltmall.api.manager.DirectorPrivilegeOrderManager;
import com.ltmall.api.weixin.pay.utils.WeixinUtils;
import com.ltmall.api.weixin.util.TemplateMessageUtil;
import org.apache.commons.lang3.time.DateUtils;

import java.math.BigDecimal;
import java.util.Date;
import java.util.Map;

public class DirectorPrivilegeOrderManagerImpl implements DirectorPrivilegeOrderManager {

    private final String                 WECHAT_NOTIFY_URL = "http://115.28.57.124/HomeFlavor/remote/directorPrivilegeOrder/wxNotify.do";
    private IDirectorPrivilegePackageDAO directorPrivilegePackageDAO;
    private IDirectorPrivilegeOrderDAO   directorPrivilegeOrderDAO;
    private IAccountDAO                  accountDAO;
    private SubUnderwritingDAO           subUnderwritingDAO;
    private WalletDAO                    walletDAO;

    public Map<String, String> create(int userId, int directorPrivilegePackageId, String ip,
                                      String openid) {
        DirectorPrivilegePackage directorPrivilegePackage = directorPrivilegePackageDAO
            .getDirectorPrivilegePackageById(directorPrivilegePackageId);

        if (directorPrivilegePackage.getLimitedPurchaseTimes() != null
            && directorPrivilegePackage.getLimitedPurchaseTimes() != 0) {
            int purchasedTimes = directorPrivilegeOrderDAO.countPurchasedTimes(
                directorPrivilegePackageId, userId);
            if (purchasedTimes >= directorPrivilegePackage.getLimitedPurchaseTimes()) {
                throw new RuntimeException("超过了购买次数");
            }
        }

        String out_trade_no = WeixinUtils.getOut_trade_no();// 交易号
        DirectorPrivilegeOrder order = new DirectorPrivilegeOrder();
        order.setUserId(userId);
        order.setDirectorPrivilegePackageId(directorPrivilegePackageId);
        order.setPay(false);
        order.setTransactionNumber(out_trade_no);
        order.setCreatedAt(new Date());
        if (!directorPrivilegeOrderDAO.save(order)) {
            throw new RuntimeException("保存数据失败");
        }

        return WeixinUtils.createAppPay(directorPrivilegePackage.getPrice(), out_trade_no,
            "乡味汇董事特权订单", ip, WECHAT_NOTIFY_URL, openid);

    }

    public void setSuccess(String tradeNo) {

        //【1】根据订单号查询订单信息
        DirectorPrivilegeOrder order = directorPrivilegeOrderDAO.getByTradeNo(tradeNo);
        if (order.getPay()) {
            throw new RuntimeException("订单已完成");
        }

        //【2】将订单设置为已支付
        order.setPay(true);
        order.setUpdatedAt(new Date());
        if (!directorPrivilegeOrderDAO.save(order)) {
            throw new RuntimeException("保存数据失败");
        }
        DirectorPrivilegePackage directorPrivilegePackage = directorPrivilegePackageDAO
            .getDirectorPrivilegePackageById(order.getDirectorPrivilegePackageId());

        //【3】为用户增加特权
        ClientAccount account = accountDAO.getAccount(null, order.getUserId());
        if (directorPrivilegePackage.getTimeMode()) {
            Date expiration = account.getPrivilegeExpiration();
            Date now = new Date();
            if (expiration == null || expiration.before(now)) {
                expiration = now;
            }
            account.setPrivilegeExpiration(DateUtils.addDays(expiration,
                directorPrivilegePackage.getDuration()));
        } else {
            Integer useageCount = account.getPrivilegeUsageCount();
            useageCount = useageCount == null ? directorPrivilegePackage.getUsageCount()
                : useageCount + directorPrivilegePackage.getUsageCount();
            account.setPrivilegeUsageCount(useageCount);
        }
        if (!accountDAO.saveClientAccount(account)) {
            throw new RuntimeException("保存数据失败");
        }

        //【4】为推荐人奖励乡币
        int price = directorPrivilegePackage.getPrice();
        //间接代理人分润
        double level1 = price * 0.3;
        //直接代理人分润
        double level2 = price * 0.15;

        //获取推荐人信息
        ClientInfo underWriterInfo = subUnderwritingDAO.getClientInfoByFansId(order.getUserId());
        if (underWriterInfo != null && price > 0) {
            //查询该用户是否有间接代理人
            int UnderwritingId = subUnderwritingDAO.referrerIdGet(underWriterInfo.getUserID());
            //有间接代理人
            if (UnderwritingId > 0) {
                //给直接代理人发放分润
                profit(order, underWriterInfo.getUserID(), level1, 1);

                //给间接代理人发放分润
                profit(order, UnderwritingId, level2, 2);
            } else {
                //给直接代理人发放分润
                profit(order, underWriterInfo.getUserID(), level1, 1);
            }

        }
    }

    /**
     * 董事套餐订单给代理人发放分润
     * 
     * @param order     订单信息
     * @param userId    获得分润的用户
     * @param amount    分润金额 
     * @param level     该分润为几级分润（1:一级代理分润；2:二级代理分润）
     */
    private void profit(DirectorPrivilegeOrder order, int userId, double amount, int level) {

        BigDecimal amountBigDecimal = BigDecimal.valueOf(amount / 100).setScale(2,
            BigDecimal.ROUND_HALF_UP);

        //增加董事特权订单信息
        if (!directorPrivilegeOrderDAO.addSubUnderwriterTotalIncome(userId, amount / 100)) {
            throw new RuntimeException("保存数据失败");
        }

        //增加推荐人收入订单信息
        ThSubUnderwritingIncomes incomeRecord = new ThSubUnderwritingIncomes();
        incomeRecord.setAmount(amountBigDecimal);
        incomeRecord.setState(1);
        incomeRecord.setUserId(userId);
        incomeRecord.setChannelType(3);
        incomeRecord.setChannelId(order.getId());
        incomeRecord.setLevel(level);
        incomeRecord.setCreatedAt(new Date());
        if (!directorPrivilegeOrderDAO.saveThSubUnderwritingIncomes(incomeRecord)) {
            throw new RuntimeException("保存数据失败");
        }

        //发送通知
        ThClientPlatforms thClientPlatforms = accountDAO.getClientPlatformByUserId(userId);
        TemplateMessageUtil.sendDirectorPrivilegeOrderIncomeMessage(thClientPlatforms.getOpenId(),
            amount / 100);
    }

    public IDirectorPrivilegePackageDAO getDirectorPrivilegePackageDAO() {
        return directorPrivilegePackageDAO;
    }

    public void setDirectorPrivilegePackageDAO(IDirectorPrivilegePackageDAO directorPrivilegePackageDAO) {
        this.directorPrivilegePackageDAO = directorPrivilegePackageDAO;
    }

    public IDirectorPrivilegeOrderDAO getDirectorPrivilegeOrderDAO() {
        return directorPrivilegeOrderDAO;
    }

    public void setDirectorPrivilegeOrderDAO(IDirectorPrivilegeOrderDAO directorPrivilegeOrderDAO) {
        this.directorPrivilegeOrderDAO = directorPrivilegeOrderDAO;
    }

    public IAccountDAO getAccountDAO() {
        return accountDAO;
    }

    public void setAccountDAO(IAccountDAO accountDAO) {
        this.accountDAO = accountDAO;
    }

    public SubUnderwritingDAO getSubUnderwritingDAO() {
        return subUnderwritingDAO;
    }

    public void setSubUnderwritingDAO(SubUnderwritingDAO subUnderwritingDAO) {
        this.subUnderwritingDAO = subUnderwritingDAO;
    }

    public WalletDAO getWalletDAO() {
        return walletDAO;
    }

    public void setWalletDAO(WalletDAO walletDAO) {
        this.walletDAO = walletDAO;
    }
}
